﻿using AntdUI;
using System.Linq.Expressions;
using System.Reflection;
using WenAntdUI.Helps;
using WenAntdUI.Services;

namespace WenAntdUI.Extensions;

public class TableColumnBuilder<T>(AntdUI.Table table) where T : class
{
    private DictService? _dictService;
    private DictService? dictService => _dictService ??= App.GetService<DictService>();
    /// <summary>
    /// 添加列
    /// </summary>
    /// <param name="expression"></param>
    /// <param name="action"></param>
    /// <returns></returns>
    public TableColumnBuilder<T> Add(Expression<Func<T, object>>? expression, Action<AntdUI.Column>? action = null)
    {
        var member = expression?.GetMemberExpression();
        if (member == null) return this;

        var (name, title, col) = GetColumnInfo(member.Member);
        if (col?.Show == false) return this;

        var column = CreateColumn(member.Member, member.Type, name, title, col);
        action?.Invoke(column);
        table.Columns.Add(column);
        return this;
    }

    /// <summary>
    /// 添加列
    /// </summary>
    /// <param name="pinfo"></param>
    /// <param name="action"></param>
    /// <returns></returns>
    public TableColumnBuilder<T> Add(PropertyInfo pinfo, Action<AntdUI.Column>? action = null)
    {
        var (name, title, col) = GetColumnInfo(pinfo);
        if (col?.Show == false) return this;
        var column = CreateColumn(pinfo, pinfo.PropertyType, name, title, col);
        action?.Invoke(column);
        table.Columns.Add(column);
        return this;
    }

    private static (string name, string title, ColAttribute? col) GetColumnInfo(MemberInfo member)
    {
        var name = member.Name;
        var title = member.GetCustomAttribute<DisplayNameAttribute>()?.DisplayName ?? name;
        var col = member.GetCustomAttribute<ColAttribute>();
        return (col?.Name ?? name, title, col);
    }
    private Column CreateColumn(MemberInfo memberInfo, Type type, string name, string title, ColAttribute? col)
    {
        Column c = type == typeof(bool)
            ? new ColumnCheck(name, title)
            : new Column(name, title);

        var category = memberInfo.GetCustomAttribute<DictAttribute>()?.Category;

        if (type.IsEnum)
        {
            c.Render = (v, r, i) => RenderEnumValue(v, type);
        }
        else if (type == typeof(Color))
        {
            c.Render = (v, r, i) => RnderColorCellTag((Color)v);
        }
        else if (type == typeof(Image))
        {
            c.Render = (v, r, i) => RenderCellImage(v);
        }
        else if (category != null)
        {
            c.Render = (v, r, i) => RenderDictCell(v, category);
        }

        if (col != null)
        {
            c.Fixed = col.IsFixed;
            c.SortOrder = col.IsSortOrder;
            c.Width = col.Width == 0 ? null : col.Width.ToString();
        }

        return c;
    }

    /// <summary>
    /// 获取枚举值 CellTag标签
    /// </summary>
    /// <param name="v"></param>
    /// <param name="enumType"></param>
    /// <returns></returns>
    private static CellTag RenderEnumValue(object? v, Type enumType)
    {
        if (v == null) return new CellTag("", TTypeMini.Info);
        var val = (Enum)Enum.ToObject(enumType, v);
        return new CellTag(val.GetDescription(), TTypeMini.Info);
    }

    private static CellTag RnderColorCellTag(Color? v)
    {
        float brightness = v is null ? 0 :
            (v?.R * 0.299f) + (v?.G * 0.587f) + (v?.B * 0.114f) ?? 0;
        return new CellTag(ColorTranslator.ToHtml(v ?? Color.Empty))
        {
            Back = v,
            Fore = (brightness > 128) ? Color.Black : Color.White
        };
    }

    private CellTag RenderDictCell(object? v, string category)
    {
        var ds = dictService ?? throw new Exception("字典服务未注册");
        if (v == null) return new CellTag("", TTypeMini.Info);
        var val = v.ToString();
        var dictItem = ds.Get(category, val);
        var color = dictItem?.Color??Color.Empty;
        float brightness = (color.R * 0.299f) + (color.G * 0.587f) + (color.B * 0.114f);
        return new CellTag(dictItem?.Name ?? val, TTypeMini.Info)
        {
            Back = color,
            Fore = (brightness > 128) ? Color.Black : Color.White
        };
    }

    private CellImage RenderCellImage(object? v)
    {
        if (v is Image image)
        {
            return new CellImage(image);
        }
        return null;
    }

    /// <summary>
    /// 添加列
    /// </summary>
    /// <param name="expression"></param>
    /// <param name="width"></param>
    /// <param name="action"></param>
    /// <returns></returns>
    public TableColumnBuilder<T> Add(Expression<Func<T, object>>? expression, int width, Action<AntdUI.Column>? action = null)
    {
        Add(expression, a => { a.Width = width.ToString(); action?.Invoke(a); });
        return this;
    }

    /// <summary>
    /// 添加树结构列
    /// </summary>
    /// <param name="expression"></param>
    /// <returns></returns>
    public TableColumnBuilder<T> AddTreeColumn(Expression<Func<T, object>>? expression)
    {
        if (expression?.Body is MemberExpression m)
        {
            AddTreeColumn(m.Member.Name);
        }
        return this;
    }
    /// <summary>
    /// 添加树结构列
    /// </summary>
    /// <param name="keytree"></param>
    /// <returns></returns>
    public TableColumnBuilder<T> AddTreeColumn(string keytree)
    {
        var col = new AntdUI.Column("TreeColumn", "")
        {
            KeyTree = keytree,
            Width = "auto"
        };
        table.Columns.Add(col);
        return this;
    }
}